home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Tools - Objects / MacApp / MacApp 3.0a2 / Libraries / UClipboardMgr.cp < prev    next >
Encoding:
Text File  |  1991-05-01  |  12.2 KB  |  478 lines  |  [TEXT/MPS ]

  1. // UClipboard.cp 
  2. // Copyright © 1984-1991 by Apple Computer Inc. All rights reserved.
  3.  
  4. #ifndef __UCLIPBOARDMGR__
  5. #include <UClipboardMgr.h>
  6. #endif
  7.  
  8. #ifndef __STDIO__
  9. #include <StdIo.h>
  10. #endif
  11.  
  12. #ifndef __UWINDOW__
  13. #include <UWindow.h>
  14. #endif
  15.  
  16. #ifndef __UAPPLICATION__
  17. #include <UApplication.h>
  18. #endif
  19.  
  20. #ifndef __UMACAPPUTILITIES__
  21. #include <UMacAppUtilities.h>
  22. #endif
  23.  
  24. #ifndef __UMACAPPGLOBALS__
  25. #include <UMacAppGlobals.h>
  26. #endif
  27.  
  28. #ifndef __UMEMORY__
  29. #include <UMemory.h>
  30. #endif
  31.  
  32. #ifndef __UMENUMGR__
  33. #include <UMenuMgr.h>
  34. #endif
  35.  
  36. #ifndef __UERRORMGR__
  37. #include <UErrorMgr.h>
  38. #endif
  39.  
  40. #ifndef __UDESKSCRAPVIEW__
  41. #include <UDeskScrapView.h>
  42. #endif
  43.  
  44. #ifndef __UVIEWSERVER__
  45. #include <UViewServer.h>
  46. #endif
  47.  
  48. TClipboardMgr* gClipboardMgr = NULL;                    // declared in interface
  49.  
  50. //--------------------------------------------------------------------------------------------------
  51. #pragma segment MAInit
  52.  
  53. pascal void TClipboardMgr::Initialize(void)    // Override
  54. {
  55.     inherited::Initialize();
  56.     
  57.     fClipUndoView = NULL;
  58.     fClipView = NULL;
  59.     fClipWindow = NULL;
  60.     fClipOrphanage = NULL;
  61.     fGotClipType = FALSE;
  62.     // ###SRF gVarClipPicSize = FALSE;            // temporary
  63.  
  64.     fOldScrapStuff.scrapSize = 0;
  65.     fOldScrapStuff.scrapHandle = NULL;
  66.     fOldScrapStuff.scrapCount = 0;
  67.     fOldScrapStuff.scrapState = 0;
  68.     fOldScrapStuff.scrapName = NULL;
  69.  
  70.     fNewScrapStuff = fOldScrapStuff;
  71. }
  72.  
  73. //--------------------------------------------------------------------------------------------------
  74. #pragma segment MAInit
  75.  
  76. pascal void TClipboardMgr::IClipboardMgr(void)
  77. {
  78.     this->IEvtHandler(NULL);
  79.  
  80.     this->AbsorbScrapStuff();                            // get the initial state of the desk scrap 
  81.     gClipboardMgr = this;
  82. }
  83.  
  84. //--------------------------------------------------------------------------------------------------
  85. #pragma segment MAClipboard
  86.  
  87. pascal void TClipboardMgr::AbandonUndoClipboard(void)
  88. {
  89.     if (fClipUndoView)
  90.     {
  91. #if qDebug
  92.         if (fClipUndoView == fClipView)
  93.             ProgramBreak("About to Free view both in clip and undo Clip!");
  94. #endif
  95.         fClipUndoView->FreeFromClipboard();
  96.         fClipUndoView = NULL;
  97.     }
  98. }
  99.  
  100. //--------------------------------------------------------------------------------------------------
  101. #pragma segment MAActivate
  102.  
  103. pascal void TClipboardMgr::AboutToLoseControl(Boolean convertClipboard)    //??? Needs rework.
  104. {
  105.     long err;
  106.     FailInfo fi;
  107.     TCommand * lastCommand;
  108.  
  109.     if (convertClipboard)
  110.     {
  111.         lastCommand = this->GetLastCommand();
  112.         if ((lastCommand != NULL) && (lastCommand->fChangesClipboard))
  113.             this->CommitLastCommand();
  114.  
  115.         if ((fClipView != NULL) && (!fClipWrittenToDeskScrap))
  116.         {
  117.             err = ZeroScrap();
  118.             if (fi.Try())
  119.             {
  120.                 fClipView->WriteToDeskScrap();
  121.                 fi.Success();
  122.             }
  123.             else    // Recover
  124.             {
  125. #if qDebugMsg
  126.                 fprintf(stderr,"Can't use clipboard data outside this app");
  127. #endif
  128.                 if (fi.message == 0)
  129.                     fi.message = msgExportClipFailed;
  130.                 gApplication->ShowError(fi.error, fi.message);
  131.             }
  132.             fClipWrittenToDeskScrap = TRUE;
  133.             this->AbsorbScrapStuff();            // ??? correct post-error reentry point? 
  134.         }
  135.     }
  136. }
  137.  
  138. //--------------------------------------------------------------------------------------------------
  139. #pragma segment MAApplicationRes
  140.  
  141. pascal void TClipboardMgr::AbsorbScrapStuff(void)
  142. {
  143.     fOldScrapStuff = fNewScrapStuff;            // stash previous version, for later change-checkage
  144.     fNewScrapStuff = *(InfoScrap());            // Copy over from low memory to our private
  145.                                                 // global record
  146. }
  147.  
  148. //--------------------------------------------------------------------------------------------------
  149. #pragma segment MAApplicationRes
  150.  
  151. pascal void TClipboardMgr::CheckDeskScrap(void)
  152. {
  153.     OSErr err;
  154.     TCommand * lastCommand;
  155.  
  156.     this->AbsorbScrapStuff();
  157.  
  158.     if (fOldScrapStuff.scrapCount != fNewScrapStuff.scrapCount)
  159.     {
  160.         lastCommand = this->GetLastCommand();
  161.         if ((lastCommand != NULL) && (lastCommand->fChangesClipboard))
  162.             this->CommitLastCommand();
  163.         fClipView->FreeFromClipboard();            // AbandonCurrentClipboard 
  164.         fClipView = NULL;                        // no reason to have an Undo clipboard 
  165.  
  166.         // If the scrap is in memory and we are low on memory, then write the scrap to disk.
  167.         if ((fNewScrapStuff.scrapState > 0) && MemSpaceIsLow())
  168.             err = (OSErr)UnloadScrap();            // Write the scrap to disk. How should we
  169.                                                 // handle the error???
  170.         this->ReadFromDeskScrap();
  171.     }
  172. }
  173.  
  174. //--------------------------------------------------------------------------------------------------
  175. #pragma segment MAClipboard
  176.  
  177. pascal void TClipboardMgr::ClaimClipboard(TView* clipView)
  178. {
  179.     this->AbandonUndoClipboard();                // free up any old UNDO stuff 
  180.     fClipUndoView = fClipView;                    // Copy current clipboard contents to the Undo side
  181.     if (clipView)
  182.         this->SetClipView(clipView);            // Will install it as fClipView 
  183.     else
  184.     {
  185. #if qDebug
  186.         ProgramBreak("Claiming clipboard with null view");
  187. #endif
  188.     }
  189.     fClipClaimed = TRUE;
  190. }
  191.  
  192. //--------------------------------------------------------------------------------------------------
  193. #pragma segment MAClipboard
  194.  
  195. pascal long TClipboardMgr::GetDataToPaste(Handle aDataHandle,
  196.                                           ResType& dataType)
  197. {
  198.     OSErr err;
  199.  
  200.     if (fGotClipType)
  201.     {
  202.         dataType = fPrefClipType;
  203.         err = (OSErr)fClipView->GivePasteData(aDataHandle, dataType);
  204.         if (err < 0)
  205.             Failure(err, 0);
  206.     }
  207.     else
  208.     {
  209. #if qDebug
  210.         ProgramBreak("GetDataToPaste called when fGotClipType was FALSE");
  211. #endif
  212.     }
  213.     return err;
  214. }
  215.  
  216. //--------------------------------------------------------------------------------------------------
  217. #pragma segment MAInit
  218.  
  219. pascal void TClipboardMgr::Launch(void)
  220. {
  221.     // Create the clip window and default view 
  222.     fClipWindow = this->MakeClipboardWindow();
  223.     fClipOrphanage = fClipWindow->FindSubView(kIDClipView);
  224.     FailNILResource((Handle)fClipOrphanage);
  225.  
  226.     // Get the clipboard manager in the eventhandler chain after the application 
  227.     gApplication->AddHandler(this);
  228.  
  229.     this->AbsorbScrapStuff();
  230.     this->ReadFromDeskScrap();
  231. }
  232.  
  233. //--------------------------------------------------------------------------------------------------
  234. #pragma segment MAInit
  235.  
  236. pascal TWindow* TClipboardMgr::MakeClipboardWindow(void)
  237. {
  238.     TWindow * aWindow;
  239.  
  240.     if (qTemplateViews)
  241.         aWindow = gViewServer->NewTemplateWindow(kIDClipWindow, NULL);
  242.     else
  243.     {
  244.         TDeskScrapView * aDeskScrapView;
  245.  
  246.         aDeskScrapView = new TDeskScrapView;
  247.         aDeskScrapView->IDeskScrapView();
  248.         aDeskScrapView->fIdentifier = KIDClipView;
  249.         aWindow = gViewServer->NewSimpleWindow(kIDClipWindow, TRUE, TRUE, NULL, aDeskScrapView);
  250.     }
  251.     
  252.     if (aWindow)
  253.     {
  254.         aWindow->fHideOnSuspend = TRUE;
  255.         aWindow->fHandlesCursor = FALSE;
  256.         aWindow->fLetsSubViewsHandleCursor = FALSE;
  257.     }
  258.     return aWindow;
  259. }
  260.  
  261. //--------------------------------------------------------------------------------------------------
  262. #pragma segment MAClipboard
  263.  
  264. pascal void TClipboardMgr::ReadFromDeskScrap(void)
  265. {
  266.     TView * aViewForClipboard;
  267.     FailInfo fi;
  268.  
  269.     if (fi.Try())
  270.     {
  271.         aViewForClipboard = this->MakeViewForAlienClipboard();
  272.         fi.Success();
  273.     }
  274.     else    // Recover
  275.     {
  276.         aViewForClipboard = fClipOrphanage;
  277.         if (fi.message == 0)
  278.             fi.message = msgImportClipFailed;
  279.         gApplication->ShowError(fi.error, fi.message);
  280.     }
  281.  
  282.     this->ClaimClipboard(aViewForClipboard);
  283. }
  284.  
  285. //--------------------------------------------------------------------------------------------------
  286. #pragma segment MAClipboard
  287.  
  288. pascal TView* TClipboardMgr::MakeViewForAlienClipboard(void)
  289. {
  290.     TView * aView;
  291.  
  292.     aView = gApplication->MakeViewForAlienClipboard();
  293.     if (!aView)
  294.         aView = fClipOrphanage;
  295.  
  296.     FailNIL((Ptr)aView);
  297.     return aView;
  298. }
  299.  
  300. //--------------------------------------------------------------------------------------------------
  301. #pragma segment MAApplicationRes
  302.  
  303. pascal void TClipboardMgr::RegainControl(Boolean checkClipboard)
  304. {
  305.     if (checkClipboard)
  306.         this->CheckDeskScrap();
  307. }
  308.  
  309. //--------------------------------------------------------------------------------------------------
  310. #pragma segment MAClipboard
  311.  
  312. pascal void TClipboardMgr::SetClipView(TView* clipView)
  313. {
  314.     if (fClipWindow)
  315.     {
  316.         TView * theSuperView;
  317.  
  318.         if (fClipWindow->CountSubViews() > 0)
  319.             theSuperView = (TView *)(fClipWindow->fSubViews->First());
  320.         else
  321.             theSuperView = fClipWindow;
  322.             
  323.         CSubViewIterator iter(theSuperView);
  324.         
  325.         for (TView* theSubView = iter.FirstSubView(); iter.More(); theSubView = iter.NextSubView())
  326.             theSuperView->RemoveSubView(theSubView);
  327.  
  328.         theSuperView->AddSubView(clipView);
  329.         clipView->fSuperView = theSuperView;
  330.         clipView->SuperViewChangedSize(gZeroVPt, kDontInvalidate);
  331.         clipView->RevealTop(kDontRedraw);
  332.         fClipWindow->ForceRedraw();
  333.         fClipWindow->SetTarget(fClipWindow);
  334.         fClipWrittenToDeskScrap = clipView == fClipOrphanage;
  335.     }
  336.     else
  337.     {
  338. #if qDebug
  339.         ProgramBreak("SetClipView in absence of fClipWindow");
  340. #endif
  341.     }
  342.  
  343.     clipView->SetEnable(FALSE);                    // Ignore clicks while in clipboard views
  344.     fClipView = clipView;
  345. }
  346.  
  347. //--------------------------------------------------------------------------------------------------
  348. #pragma segment MAClipboard
  349.  
  350. pascal void TClipboardMgr::SwapClipViews(void)
  351. {
  352.     TView * tempClipView;
  353.  
  354.     tempClipView = fClipUndoView;
  355.     fClipUndoView = fClipView;
  356.  
  357.     if (tempClipView)
  358.         this->SetClipView(tempClipView);          // Installs old Undo clipboard as current clipboard
  359. #if qDebug
  360.     else
  361.         ProgramBreak("SwapClipViews finds undo clipboard was NULL");
  362. #endif
  363.  
  364. }
  365.  
  366. //--------------------------------------------------------------------------------------------------
  367. #pragma segment MAApplicationRes
  368.  
  369. pascal void TClipboardMgr::DoSetupMenus(void)
  370. {
  371.     fGotClipType = FALSE;
  372.     inherited::DoSetupMenus();
  373.  
  374.     Enable(cShowClipboard, TRUE);
  375.  
  376.     SetMenuState(cShowClipboard, kIDBuzzString, bzShowClip, bzHideClip, fClipWindow == gApplication->GetActiveWindow());
  377.  
  378. }
  379.  
  380. //--------------------------------------------------------------------------------------------------
  381. #pragma segment MAApplicationRes
  382.  
  383. pascal void TClipboardMgr::CanPaste(ResType aClipType)
  384. {
  385.     if (fClipView)
  386.         if (fClipView->ContainsClipType(aClipType))
  387.         {
  388.             fGotClipType = TRUE;
  389.             fPrefClipType = aClipType;
  390.         }
  391.  
  392.     if (!gApplication->fSysWindowActive)
  393.         Enable(cPaste, fGotClipType);
  394. }
  395.  
  396. //--------------------------------------------------------------------------------------------------
  397. #pragma segment MASelCommand
  398.  
  399. pascal void TClipboardMgr::DoMenuCommand(CmdNumber aCmdNumber)
  400. {
  401.     switch (aCmdNumber)
  402.     {
  403.         case cShowClipboard:
  404.             if (fClipWindow == gApplication->GetActiveWindow())
  405.                 fClipWindow->Close();            // Hide the clipboard 
  406.             else
  407.             {
  408.                 fClipWindow->Open();
  409.                 fClipWindow->Select();
  410.             }
  411.             break;
  412.         default:
  413.             inherited::DoMenuCommand(aCmdNumber);
  414.             break;
  415.     }
  416. }
  417.  
  418. //--------------------------------------------------------------------------------------------------
  419. #pragma segment MAFields
  420.  
  421. pascal void TClipboardMgr::Fields(TObject* obj)    // override 
  422. {
  423.     obj->DoToField("TClipboardMgr", (Ptr)NULL, bClass);
  424.     obj->DoToField("fClipClaimed", (Ptr) & fClipClaimed, bBoolean);
  425.     obj->DoToField("fClipOrphanage", (Ptr) & fClipOrphanage, bObject);
  426.     obj->DoToField("fClipUndoView", (Ptr) & fClipUndoView, bObject);
  427.     obj->DoToField("fClipView", (Ptr) & fClipView, bObject);
  428.     obj->DoToField("fClipWindow", (Ptr) & fClipWindow, bObject);
  429.     obj->DoToField("fClipWrittenToDeskScrap", (Ptr) & fClipWrittenToDeskScrap, bBoolean);
  430.     obj->DoToField("fGotClipType", (Ptr) & fGotClipType, bBoolean);
  431.     //###SRF     obj->DoToField("gVarClipPicSize", (Ptr)&gVarClipPicSize, bBoolean);
  432.     obj->DoToField("fPrefClipType", (Ptr) & fPrefClipType, bOSType);
  433.     obj->DoToField("fNewScrapStuff", (Ptr) & fNewScrapStuff, bScrapStuff);
  434.     obj->DoToField("fOldScrapStuff", (Ptr) & fOldScrapStuff, bScrapStuff);
  435.  
  436.     inherited::Fields(obj);
  437. }
  438.  
  439. //--------------------------------------------------------------------------------------------------
  440. #pragma segment MATerminate
  441.  
  442. pascal void TClipboardMgr::Close(void)
  443. {
  444.     LoadScrap();                                // ??? 
  445. }
  446.  
  447. //--------------------------------------------------------------------------------------------------
  448. #pragma segment MAApplicationRes
  449.  
  450. pascal OSErr TClipboardMgr::PutDeskScrapData(ResType aResType,
  451.                                              Handle aDataHandle)
  452. {
  453.     long err;
  454.     SignedByte savedState;
  455.  
  456.     savedState = LockHandleHigh(aDataHandle);
  457.     err = PutScrap(GetHandleSize(aDataHandle), aResType, (*aDataHandle));
  458.     HSetState(aDataHandle, savedState);
  459. #if qDebugMsg
  460.     if (err != noErr)
  461.         fprintf(stderr,"Error from PutScrap is: %d\n");
  462. #endif
  463.     return err;
  464. }
  465.  
  466. //--------------------------------------------------------------------------------------------------
  467. #pragma segment MAInit
  468.  
  469. pascal void InitUClipboardMgr(void)
  470. {
  471.     TClipboardMgr * aClipboardMgr;
  472.  
  473.     aClipboardMgr = new TClipboardMgr;
  474.     aClipboardMgr->IClipboardMgr();
  475. }
  476.  
  477.  
  478.